﻿using System;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using VerifyArgs;
using System.Reflection;

namespace EP.Caching.Attributes {
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	public sealed class AddToCacheKeyAttribute : Attribute {
		private readonly string _propertyName;
		public string PropertyName { get { return _propertyName; } }

		private readonly string _appendKey;
		public string AppendKey { get { return _appendKey; } }

		public AddToCacheKeyAttribute(string propertyName, string appendKey) {
			//Verify.Args(new { propertyName, appendKey }).NotNullOrEmpty();

			if (string.IsNullOrWhiteSpace(propertyName) && string.IsNullOrWhiteSpace(appendKey))
				throw new ArgumentException("propertyName + appendKey both cannot be null or empty");

			_propertyName = propertyName;
			_appendKey = appendKey;
		}

		public int Order { get; set; }

		public string GetKey(MethodBase input, object target) {
			Verify.Args(new { input, input.DeclaringType, target }).NotNull();

			var retVal = new StringBuilder();

			if (!string.IsNullOrWhiteSpace(_propertyName)) {
				var prop = input.DeclaringType.GetProperty(_propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
				if (prop != null)
					retVal.Append(prop.GetValue(target, null));
			}

			if (!string.IsNullOrWhiteSpace(_appendKey))
				retVal.Append(_appendKey);

			return retVal.ToString();
		}
	}
}
